/**
 * Notes: 项目控制器
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY cclinux0730 (wechat)
 * Date: 2023-08-30 19:20:00
 */

const BaseProjectController = require('./base_project_controller.js');
const ProjectModel = require('../model/project_model.js');
const timeUtil = require('../../../framework/helpers/time_util.js');
const dataUtil = require('../../../framework/helpers/data_util.js');
const appCode = require('../../../framework/core/app_code.js');
const config = require('../../../config/config.js');
const ProjectService = require('../service/project_service.js');
const AppError = require('../../../framework/core/app_error.js');
const InitCloudCollections = require('../init/init_cloud_collections.js');
const cloudBase = require('../../../framework/cloud/cloud_base.js');

class ProjectController extends BaseProjectController {
	constructor(route, openId, event) {
		super(route, openId, event);
		this._dbInitialized = false;
	}

	/** 创建服务实例 */
	_getService() {
		const service = new ProjectService();
		// 设置用户ID
		service._userId = this._userId;
		return service;
	}

	/** 初始化设置 */
	async initSetup() {
		// 调用父类的初始化方法
		await super.initSetup();
		
		console.log('[ProjectController] 初始化数据库集合...');
		
		try {
			// 确保数据库集合已初始化
			const result = await InitCloudCollections.initCollections();
			console.log('[ProjectController] 数据库初始化结果:', result);
			return result;
		} catch (err) {
			console.error('[ProjectController] 初始化数据库集合失败:', err);
			return { code: -1, message: `初始化数据库集合失败: ${err.message}` };
		}
	}

	/** 获取项目列表 */
	async getProjectList() {
		// 数据校验
		let rules = {
			search: 'string|min:0|max:100|name=搜索关键词',
			sortType: 'string|min:0|max:50|name=搜索排序类型',
			sortVal: 'string|min:0|max:50|name=搜索排序值',
			page: 'must|int|default=1|name=当前页码',
			size: 'must|int|default=20|name=每页记录数',
			status: 'string|name=状态',
			department: 'string|name=部门',
			cate: 'int|name=分类',
			bizManager: 'int|name=业务负责人',
			devManager: 'int|name=研发负责人',
		};

		// 取得数据
		const params = this.validateData(rules);

		// 调用项目模型进行查询（确保返回值安全）
		try {
			console.log('[getProjectList] 输入参数:', params);
			
			// 调用model方法获取数据
			const result = await ProjectModel.getProjectList(params);
			console.log('[getProjectList] 获取成功');
			
			return result;
		} catch (err) {
			console.error('[getProjectList] 获取项目列表失败:', err);
			
			// 返回空结果而不是抛出异常，确保前端不会崩溃
			return {
				list: [],
				total: 0,
				page: params.page,
				size: params.size
			};
		}
	}

	/** 获取项目详情 */
	async getProjectDetail() {
		// 数据校验
		let rules = {
			id: 'must|id',
		};

		// 取得数据
		let input = this.validateData(rules);
		console.log('[getProjectDetail] 输入参数:', input);

		// 使用辅助方法创建服务实例
		const projectService = this._getService();

		// 获取详情
		let detail = await projectService.getProjectDetail(input.id);
		
		return detail;
	}

	/** 创建项目 */
	async createProject() {
		// 初始化数据库
		await this.initSetup();
		
		try {
			// 记录原始请求数据，便于调试
			console.log('[createProject] 原始请求数据:', JSON.stringify(this._request, null, 2));
			
			// 特殊处理霍尔和磁编项目类型，这两种类型不需要产品参数
			if (this._request.projectType === '霍尔' || this._request.projectType === '磁编') {
				console.log('[createProject] 特殊项目类型:', this._request.projectType, '，移除产品参数字段');
				
				// 保留基础字段，移除产品参数相关字段
				const baseFields = [
					'_id', 'customerName', 'model', 'projectType', 'projectTypeName',
					'startDate', 'deadline', 'priority', 'description', 'hasSample',
					'sampleCount', 'sampleImages', 'attachments', 'isActive', 'isOverdue',
					'status', 'statusText', 'level1', 'daysTillDeadline'
				];
				
				const cleanedRequest = {};
				for (let field of baseFields) {
					if (this._request[field] !== undefined) {
						cleanedRequest[field] = this._request[field];
					}
				}
				
				// 替换原始请求对象
				this._request = cleanedRequest;
				console.log('[createProject] 清理后的请求数据:', JSON.stringify(this._request, null, 2));
			} else {
				// 正常处理其他项目类型
				// 过滤请求数据，只保留需要的字段
				const validFields = [
					// 基本字段
					'name', 'applicationType', 'startDate', 'deadline', 'leader', 'department', 
					'priority', 'status', 'description', 'customerName',
					
					// 产品参数字段
					'workTemp', 'certification', 'lowPower', 'startupTime', 'conformalCoating',
					'ratedVoltage', 'maxPower', 'maxSpeed', 'polePairs', 'hasHall', 'hasFG',
					'controlMode', 'controlAlgorithm', 'rotation', 'hasBrake',
					
					// 保护参数字段
					'stallProtection', 'overvoltageProtection', 'undervoltageProtection',
					'temperatureProtection', 'overcurrentProtection', 'currentLimitProtection',
					'blockageProtection', 'phaseProtection',
					
					// PROJECT_前缀字段
					'PROJECT_CODE', 'PROJECT_NAME', 'PROJECT_DESC', 'PROJECT_CATE', 'PROJECT_PRIORITY',
					'PROJECT_CUSTOMER_NAME', 'PROJECT_START_DATE', 'PROJECT_END_DATE', 'PROJECT_PLAN_START_DATE',
					'PROJECT_PLAN_END_DATE', 'PROJECT_STATUS', 'PROJECT_SUB_STATUS', 'PROJECT_ACTIVE_STATE',
					'PROJECT_ACTIVE_SUB_STATE', 'PROJECT_PROGRESS', 'PROJECT_TITLE'
				];
				
				// 创建一个只包含有效字段的新请求对象
				const cleanedRequest = {};
				for (let field of validFields) {
					if (this._request[field] !== undefined) {
						cleanedRequest[field] = this._request[field];
					}
				}
				
				// 临时替换原始请求对象
				const originalRequest = this._request;
				this._request = cleanedRequest;
			}
			
			// 数据校验 - 只对必填字段进行must校验
			let rules = {
				// 基础信息字段 - 所有项目类型都要验证
				model: 'must|string|min:2|max:50|name=型号',
				projectType: 'must|string|max:50|name=项目类型',
				customerName: 'must|string|max:50|name=客户名称',
				startDate: 'must|int|name=开始日期',
				deadline: 'must|int|name=截止日期',
				priority: 'must|string|in:low,normal,high,urgent|name=优先级',
				
				// 可选字段
				description: 'string|max:500|name=项目描述',
				hasSample: 'string|max:10|name=有无样品',
				sampleCount: 'string|max:10|name=样品数量',
				sampleImages: 'array|name=样品图片',
				attachments: 'array|name=附件',
				
				// 条件字段 - 非霍尔和磁编类型才验证
				applicationType: 'string|max:50|name=应用类型',
				workTemp: 'string|max:50|name=工作环境温度',
				certification: 'string|max:100|name=认证要求',
				lowPower: 'string|max:50|name=低功耗要求',
				startupTime: 'string|max:50|name=启动时间要求',
				conformalCoating: 'string|max:10|name=三防漆要求',
				ratedVoltage: 'string|max:50|name=额定电压',
				maxPower: 'string|max:50|name=最大功率',
				maxSpeed: 'string|max:50|name=最高转速',
				polePairs: 'string|max:10|name=极对数',
				hasHall: 'string|max:10|name=霍尔',
				hasFG: 'string|max:10|name=FG',
				controlMode: 'string|max:20|name=控制方式',
				controlAlgorithm: 'string|max:20|name=控制算法',
				rotation: 'string|max:20|name=正反转',
				hasBrake: 'string|max:10|name=刹车',
				stallProtection: 'string|max:20|name=堵转保护',
				overvoltageProtection: 'string|max:20|name=过压保护',
				undervoltageProtection: 'string|max:20|name=欠压保护',
				temperatureProtection: 'string|max:20|name=温度保护',
				overcurrentProtection: 'string|max:20|name=过流保护',
				currentLimitProtection: 'string|max:20|name=限流保护',
				blockageProtection: 'string|max:20|name=堵孔保护',
				phaseProtection: 'string|max:20|name=缺相保护',
				
				// 系统字段
				PROJECT_CODE: 'string|max:50|name=项目编号',
				PROJECT_NAME: 'string|max:50|name=项目名称',
				PROJECT_DESC: 'string|max:500|name=项目描述',
				PROJECT_CATE: 'int|name=项目分类',
				PROJECT_PRIORITY: 'string|max:20|name=项目优先级',
				PROJECT_CUSTOMER_NAME: 'string|max:50|name=客户名称',
				PROJECT_START_DATE: 'int|name=项目开始日期',
				PROJECT_END_DATE: 'int|name=项目结束日期',
				PROJECT_PLAN_START_DATE: 'int|name=计划开始日期',
				PROJECT_PLAN_END_DATE: 'int|name=计划结束日期',
				PROJECT_STATUS: 'int|name=项目状态',
				PROJECT_SUB_STATUS: 'string|max:50|name=项目子状态',
				PROJECT_ACTIVE_STATE: 'string|max:50|name=项目活动状态',
				PROJECT_ACTIVE_SUB_STATE: 'string|max:50|name=项目活动子状态',
				PROJECT_PROGRESS: 'int|name=项目进度',
				PROJECT_TITLE: 'string|max:50|name=项目标题',
				CREATE_TIME: 'int|name=创建时间',
				UPDATE_TIME: 'int|name=更新时间'
			};

			// 取得数据
			let input = this.validateData(rules);
			console.log('[createProject] 验证后的数据：', JSON.stringify(input, null, 2));
			
			// 日期处理 - 这里只需要确保类型是整数即可，前端已经转换为时间戳
			if (input.startDate && typeof input.startDate === 'string' && isNaN(input.startDate)) {
				try {
					input.startDate = timeUtil.time2Timestamp(input.startDate);
				} catch (e) {
					console.error('[createProject] 开始日期转换错误：', e);
					throw new AppError('开始日期格式错误，请使用YYYY-MM-DD格式');
				}
			}
			if (input.startDate) input.startDate = parseInt(input.startDate);

			if (input.deadline && typeof input.deadline === 'string' && isNaN(input.deadline)) {
				try {
					input.deadline = timeUtil.time2Timestamp(input.deadline);
				} catch (e) {
					console.error('[createProject] 截止日期转换错误：', e);
					throw new AppError('截止日期格式错误，请使用YYYY-MM-DD格式');
				}
			}
			if (input.deadline) input.deadline = parseInt(input.deadline);

			// 使用辅助方法创建服务实例
			const projectService = this._getService();

			// 插入数据
			const id = await projectService.createProject(input);
			if (id) {
				console.log('[createProject] 创建成功，项目ID：', id);
				return {
					_id: id,
					success: true
				};
			} else {
				console.error('[createProject] 创建失败，没有返回ID');
				throw new AppError('创建失败，请重试');
			}
		} catch (err) {
			console.error('[createProject] 错误：', err);
			throw err; // 直接抛出错误，让框架处理
		}
	}

	/** 更新项目 */
	async updateProject() {
		// 初始化数据库
		await this.initSetup();
		
		try {
			// 记录原始请求数据，便于调试
			console.log('[updateProject] 原始请求数据:', JSON.stringify(this._request, null, 2));
			
			// 特殊处理霍尔和磁编项目类型，这两种类型不需要产品参数
			if (this._request.projectType === '霍尔' || this._request.projectType === '磁编') {
				console.log('[updateProject] 特殊项目类型:', this._request.projectType, '，移除产品参数字段');
				
				// 保留基础字段，移除产品参数相关字段
				const baseFields = [
					'_id', 'id', 'customerName', 'model', 'projectType', 'projectTypeName',
					'startDate', 'deadline', 'priority', 'description', 'hasSample',
					'sampleCount', 'sampleImages', 'attachments', 'isActive', 'isOverdue',
					'status', 'statusText', 'level1', 'daysTillDeadline'
				];
				
				const cleanedRequest = {};
				for (let field of baseFields) {
					if (this._request[field] !== undefined) {
						cleanedRequest[field] = this._request[field];
					}
				}
				
				// 替换原始请求对象
				this._request = cleanedRequest;
				console.log('[updateProject] 清理后的请求数据:', JSON.stringify(this._request, null, 2));
			}
			
			// 数据校验
			let rules = {
				id: 'must|id|name=项目ID',
				name: 'string|min:2|max:50|name=型号',
				model: 'string|min:2|max:50|name=型号',
				projectType: 'string|max:50|name=项目类型',
				customerName: 'string|max:50|name=客户名称',
				startDate: 'int|name=开始日期',
				deadline: 'int|name=截止日期',
				priority: 'string|in:low,normal,high,urgent|name=优先级',
				status: 'string|in:planning,ongoing,completed,suspended|name=状态',
				description: 'string|max:500|name=项目描述',
				
				// 可选字段
				hasSample: 'string|max:10|name=有无样品',
				sampleCount: 'string|max:10|name=样品数量',
				sampleImages: 'array|name=样品图片',
				attachments: 'array|name=附件',
				
				// 非基础项目类型才需要验证的字段
				leader: 'string|min:2|max:20|name=项目负责人',
				department: 'string|min:2|max:20|name=所属部门',
				applicationType: 'string|max:50|name=应用类型',
				workTemp: 'string|max:50|name=工作环境温度',
				certification: 'string|max:100|name=认证要求',
				lowPower: 'string|max:50|name=低功耗要求',
				startupTime: 'string|max:50|name=启动时间要求',
				conformalCoating: 'string|max:10|name=三防漆要求',
				ratedVoltage: 'string|max:50|name=额定电压',
				maxPower: 'string|max:50|name=最大功率',
				maxSpeed: 'string|max:50|name=最高转速',
				polePairs: 'string|max:10|name=极对数',
				hasHall: 'string|max:10|name=霍尔',
				hasFG: 'string|max:10|name=FG',
				controlMode: 'string|max:20|name=控制方式',
				controlAlgorithm: 'string|max:20|name=控制算法',
				rotation: 'string|max:20|name=正反转',
				hasBrake: 'string|max:10|name=刹车',
				stallProtection: 'string|max:20|name=堵转保护',
				overvoltageProtection: 'string|max:20|name=过压保护',
				undervoltageProtection: 'string|max:20|name=欠压保护',
				temperatureProtection: 'string|max:20|name=温度保护',
				overcurrentProtection: 'string|max:20|name=过流保护',
				currentLimitProtection: 'string|max:20|name=限流保护',
				blockageProtection: 'string|max:20|name=堵孔保护',
				phaseProtection: 'string|max:20|name=缺相保护',
				
				// 系统字段
				PROJECT_CODE: 'string|max:50|name=项目编号',
				PROJECT_NAME: 'string|max:50|name=项目名称',
				PROJECT_DESC: 'string|max:500|name=项目描述',
				PROJECT_CATE: 'int|name=项目分类',
				PROJECT_PRIORITY: 'string|max:20|name=项目优先级',
				PROJECT_CUSTOMER_NAME: 'string|max:50|name=客户名称',
				PROJECT_START_DATE: 'int|name=项目开始日期',
				PROJECT_END_DATE: 'int|name=项目结束日期',
				PROJECT_PLAN_START_DATE: 'int|name=计划开始日期',
				PROJECT_PLAN_END_DATE: 'int|name=计划结束日期',
				PROJECT_STATUS: 'int|name=项目状态',
				PROJECT_SUB_STATUS: 'string|max:50|name=项目子状态',
				PROJECT_ACTIVE_STATE: 'string|max:50|name=项目活动状态',
				PROJECT_ACTIVE_SUB_STATE: 'string|max:50|name=项目活动子状态',
				PROJECT_PROGRESS: 'int|name=项目进度',
				PROJECT_TITLE: 'string|max:50|name=项目标题',
				CREATE_TIME: 'int|name=创建时间',
				UPDATE_TIME: 'int|name=更新时间'
			};

			// 取得数据
			let input = this.validateData(rules);
			console.log('[updateProject] 验证后的数据：', JSON.stringify(input, null, 2));
		
			// 日期处理
			if (input.startDate && typeof input.startDate === 'string' && isNaN(input.startDate)) {
				try {
					input.startDate = timeUtil.time2Timestamp(input.startDate);
				} catch (e) {
					console.error('[updateProject] 开始日期转换错误：', e);
					throw new AppError('开始日期格式错误，请使用YYYY-MM-DD格式');
				}
			}
			if (input.startDate) input.startDate = parseInt(input.startDate);

			if (input.deadline && typeof input.deadline === 'string' && isNaN(input.deadline)) {
				try {
					input.deadline = timeUtil.time2Timestamp(input.deadline);
				} catch (e) {
					console.error('[updateProject] 截止日期转换错误：', e);
					throw new AppError('截止日期格式错误，请使用YYYY-MM-DD格式');
				}
			}
			if (input.deadline) input.deadline = parseInt(input.deadline);

			let projectId = input.id;
			delete input.id; // 不更新ID字段

			console.log('[updateProject] 正在更新项目，ID:', projectId, '数据:', JSON.stringify(input, null, 2));

			// 使用辅助方法创建服务实例
			const projectService = this._getService();

			// 更新数据
			let result = await projectService.updateProject(projectId, input);
			if (result) {
				console.log('[updateProject] 更新成功');
				return {
					result: true
				};
			} else {
				console.error('[updateProject] 更新失败');
				throw new AppError('更新失败，请重试');
			}
		} catch (err) {
			console.error('[updateProject] 错误：', err);
			throw err; // 直接抛出错误，让框架处理
		}
	}

	/** 删除项目 */
	async deleteProject() {
		// 初始化数据库
		await this.initSetup();
		
		// 数据校验
		let rules = {
			id: 'must|id|name=项目ID',
		};

		// 取得数据
		let input = this.validateData(rules);
		console.log('[deleteProject] 输入参数:', input);

		try {
			// 使用辅助方法创建服务实例
			const projectService = this._getService();

			// 删除数据
			let result = await projectService.deleteProject(input.id);
			if (result) {
				console.log('[deleteProject] 删除成功');
				return {
					result: true
				};
			} else {
				console.error('[deleteProject] 删除失败');
				throw new AppError('删除失败，请重试');
			}
		} catch (err) {
			console.error('[deleteProject] 错误：', err);
			throw err; // 直接抛出错误，让框架处理
		}
	}

	/** 管理工具：重新初始化项目数据 */
	async resetProjectData() {
		try {
			console.log('[resetProjectData] 开始重置项目数据...');
			
			// 获取云数据库实例
			const db = cloudBase.getCloud().database();
			const collection = db.collection('plm_research_project');
			
			// 先删除当前所有测试数据
			try {
				console.log('[resetProjectData] 尝试删除已有测试数据...');
				// 使用正则表达式匹配所有测试项目ID
				const deleteResult = await collection.where({
					_id: db.RegExp({
						regexp: '^test-project-',
						options: 'i',
					})
				}).remove();
				
				console.log('[resetProjectData] 删除结果:', deleteResult);
			} catch (deleteError) {
				console.error('[resetProjectData] 删除测试数据失败:', deleteError);
			}
			
			// 重新创建测试数据
			console.log('[resetProjectData] 重新创建测试数据...');
			await InitCloudCollections.createTestData();
			
			// 验证数据是否创建成功
			const countResult = await collection.count();
			console.log('[resetProjectData] 当前项目数据数量:', countResult.total);
			
			// 查询一条数据以验证
			const result = await collection.limit(1).get();
			console.log('[resetProjectData] 验证数据查询结果:', result);
			
			// 返回结果
			return this.success({
				message: '项目数据重置成功',
				count: countResult.total,
				sample: result.data && result.data.length > 0 ? result.data[0] : null
			});
		} catch (err) {
			console.error('[resetProjectData] 重置项目数据失败:', err);
			return this.fail('重置项目数据失败: ' + err.message);
		}
	}
}

module.exports = ProjectController; 